package com.yue.test.sticky;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;

import com.yue.test.R;

import java.util.ArrayList;
import java.util.List;

/**
 * @author: xiaoshi
 * @create: 2022/4/21 14:09
 * @version: 0
 * @described: recycler view 吸顶效果实现
 * https://www.jianshu.com/p/e25b2dd6d6ae
 * https://blog.csdn.net/embracecsy/article/details/118702036
 */
public class StickyTestActivity extends AppCompatActivity {
    List<Data> list = new ArrayList<>();
    TestAdapter adapter = new TestAdapter(list);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sticky_test);
        RecyclerView recyclerView = findViewById(R.id.recycler);

        for (int i = 0; i < 7; i++) {
            list.add(new Data("", "头部1"));
        }
        for (int i = 0; i < 7; i++) {
            list.add(new Data("", "头部2"));
        }
        for (int i = 0; i < 7; i++) {
            list.add(new Data("", "头部3"));
        }
        for (int i = 0; i < 7; i++) {
            list.add(new Data("", "头部4"));
        }
        for (int i = 0; i < 7; i++) {
            list.add(new Data("", "头部5"));
        }
        recyclerView.setAdapter(adapter);
        recyclerView.addItemDecoration(new StickyItemDecoration(this));
    }


    /**
     * 每个itemview都有一个ItemDecoration装饰类
     */
    private static class StickyItemDecoration extends RecyclerView.ItemDecoration {
        private static final int DIVIDER_HEIGHT_IN_PX = 1;

        private int groupHeaderHeight = 150;
        private Paint backgroundPaint;
        private Paint textPaint;
        private Rect textRect;

        public StickyItemDecoration(Context context) {
            // 头部背景画笔
            backgroundPaint = new Paint();
            backgroundPaint.setColor(Color.RED);

            // 头部文字画笔
            textPaint = new Paint();
            textPaint.setTextSize(50);
            textPaint.setColor(Color.WHITE);
            textRect = new Rect();
        }


        /**
         * item的相对偏移量
         *
         * @param outRect 指定偏移空间
         * @param view
         * @param parent
         * @param state
         */
        @Override
        public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
            super.getItemOffsets(outRect, view, parent, state);
            /*在这里设置空出head的空间*/
            TestAdapter adapter = (TestAdapter) parent.getAdapter();
            /*得到当前itemView的位置*/
            int position = parent.getChildAdapterPosition(view);
            /*判断是不是头部，是头部则流出绘制头部的空间，结合mulityAdapter可根据binder的类型或bean的类型进行判断是否是头部的itemType，也可根据itemType区分，将头部和普通布局分开*/
            if (adapter.isGroupHeader(position)) {
                // 如果是头部，就在上方预留出 Header 的高度
                outRect.set(0, groupHeaderHeight, 0, 0);
            } else {
                // 如果不是头部，则在上方留出1px画分隔线
                outRect.set(0, DIVIDER_HEIGHT_IN_PX, 0, 0);
            }
        }

        /**
         * 绘制装饰内容：itemView绘制前绘制的内容，被itemView盖住
         * 绘制普通head
         *
         * @param c      recycler的画布
         * @param parent
         * @param state
         */
        @Override
        public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
            super.onDraw(c, parent, state);
//            将布局绘制到画布上的方法
//            FrameLayout layout = new FrameLayout(this);
//            layout.draw(c);
            Log.d("shimy", "绘制");

            TestAdapter adapter = (TestAdapter) parent.getAdapter();
            int childCount = parent.getChildCount();
            int left = parent.getPaddingLeft();
            int right = parent.getWidth() - parent.getPaddingRight();
            /*开始绘制recyclerview中的每个装饰着*/
            for (int i = 0; i < childCount; i++) {
                View child = parent.getChildAt(i);
                int position = parent.getChildLayoutPosition(child);
                if (adapter.isGroupHeader(position)) {
                    /*绘制头*/
                    int bottom = child.getTop();
                    int top = bottom - groupHeaderHeight;
                    c.drawRect(left, top, right, bottom, backgroundPaint);
                    /*绘制组名称*/
                    String groupName = adapter.getGroupName(position);
                    textPaint.getTextBounds(groupName, 0, groupName.length(), textRect);
                    c.drawText(groupName, left + 20, child.getTop() -
                            groupHeaderHeight / 2 + textRect.height() / 2, textPaint);
                } else {
                    /*绘制虚线*/
                    // 不是 GroupHeader 就画一个分隔线
                    c.drawRect(left, child.getTop() - DIVIDER_HEIGHT_IN_PX, right, child.getTop(), backgroundPaint);
                }
            }
        }

        /**
         * 绘制装饰内容：item绘制后绘制的内容,盖住itemView
         * 绘制顶部sticky head
         *
         * @param c      recycler的画布
         * @param parent
         * @param state
         */
        @Override
        public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
            super.onDrawOver(c, parent, state);
            /*绘制顶部的吸附布局*/
            TestAdapter adapter = (TestAdapter) parent.getAdapter();
            //获取视图内可见的第一个item的postion,就是顶部item的position
            int position = ((LinearLayoutManager) parent.getLayoutManager()).findFirstVisibleItemPosition();
            View itemView = parent.findViewHolderForAdapterPosition(position).itemView;
            int left = parent.getPaddingLeft();
            int right = parent.getWidth() - parent.getPaddingRight();
            int top = parent.getPaddingTop();

            /*判断下一个head是否到来，到了，则需要有一个顶上去替换原head的效果*/
            boolean isGroupHeader = adapter.isGroupHeader(position + 1);
            if (isGroupHeader) {
                int bottom = Math.min(groupHeaderHeight, itemView.getBottom() - parent.getPaddingTop());
                /*继续绘制head装饰,开始收缩，bottom一直在缩小*/
                c.drawRect(left, top, right, top + bottom, backgroundPaint);
                c.clipRect(left, top, right, top + bottom);
                /*绘制文字偏移，文字也一直在向上移动*/
                String groupName = adapter.getGroupName(position);
                textPaint.getTextBounds(groupName, 0, groupName.length(), textRect);
                c.drawText(groupName, left + 20, top + bottom
                        - groupHeaderHeight / 2 + textRect.height() / 2, textPaint);
            } else {
                /*下一个head没到来，继续绘制原head在顶部*/
                c.drawRect(left, top, right, top + groupHeaderHeight, backgroundPaint);
                String groupName = adapter.getGroupName(position);
                textPaint.getTextBounds(groupName, 0, groupName.length(), textRect);
                c.drawText(groupName, left + 20, top + groupHeaderHeight / 2 + textRect.height() / 2, textPaint);
            }
        }
    }
}